package util

import (
	"fmt"
	"os/exec"
	"strings"
)

//ContainerRuntimeType 容器运行时类型，docker或者podman
type ContainerRuntimeType string

//ContainerRestartType 容器停止后的重启策略:no：容器退出时不重启,on-failure：容器故障退出（返回值非零）时重启,always：容器退出时总是重启
type ContainerRestartType string

const (
	//CRDocker docker类型的容器运行时
	CRDocker ContainerRuntimeType = "docker"
	//CRPodman podam类型的容器运行时
	CRPodman ContainerRuntimeType = "podman"
	//CRNo 容器退出时不重启
	CRNo ContainerRestartType = "no"
	//CRFailure 容器故障退出（返回值非零）时重启
	CRFailure ContainerRestartType = "on-failure"
	//CRAlways 容器退出时总是重启
	CRAlways ContainerRestartType = "always"
)

//NewContainerRuntimeClient 创建一个ContainerRuntimeClient实例，这个实例可以是Docker的也可以是Podman的
func NewContainerRuntimeClient(crt ContainerRuntimeType) ContainerRuntimeClient {
	return &containerRuntimeCmdClient{
		crt: crt,
	}
}

//ContainerRuntimeClient 容器运行时客户端
type ContainerRuntimeClient interface {
	RegistryLogin(username string, password string, registry string) bool
	Version() (string, error)
	ImagePull(imageName string, version string) string
	ImagePullByAuth(imageName string, version string, username string, password string) string
	ContainerStart(containerOption *ContainerOption) string
	ListAllImage() []ImageInfo
	ContainerStopAndRemove(containerID string)
}

//DockerClient docker客户端，执行docker命令
type containerRuntimeCmdClient struct {
	crt ContainerRuntimeType
}

//execCmd 执行命令
func (c *containerRuntimeCmdClient) execCmd(arg ...string) (string, error) {
	output, err := exec.Command(string(c.crt), arg...).Output()
	return string(output), err
}

//RegistryLogin 登录容器镜像仓库
func (c *containerRuntimeCmdClient) RegistryLogin(username string, password string, registry string) bool {
	out, err := c.execCmd("login", "--username="+username, "--password="+password, registry)
	out = strings.Replace(out, "\n", "", -1)
	if err != nil {
		fmt.Println(err)
		return false
	} else if out == "Login Succeeded\n" {
		fmt.Println(out)
		return true
	} else {
		fmt.Println(out)
		return false
	}
}

//Version 版本信息
func (c *containerRuntimeCmdClient) Version() (string, error) {
	out, err := c.execCmd("version")
	if err != nil {
		return "", err
	}
	return out, nil
}

//ImagePull 拉取容器镜像
func (c *containerRuntimeCmdClient) ImagePull(imageName string, version string) string {
	if version == "" {
		version = "latest"
	}
	out, err := c.execCmd("pull", imageName+":"+version)
	if err != nil {
		fmt.Println("err:\n" + err.Error())
	} else {
		fmt.Println(out)
		rs := strings.Split(out, "\n")
		for _, r := range rs {
			cs := strings.Split(r, ":")
			if cs[0] == "Digest" {
				return cs[2]
			}
		}
	}
	return ""
}

//ContainerStart 创建并以后台方式执行一个容器
func (c *containerRuntimeCmdClient) ContainerStart(containerOption *ContainerOption) string {
	var args = []string{"run", "-d"}
	args = append(args, containerOption.ToArg()...)
	out, err := c.execCmd(args...)
	if err != nil {
		panic(err)
	}
	return strings.Replace(out, "\n", "", -1)
}

func (c *containerRuntimeCmdClient) ImagePullByAuth(imageName string, version string, username string, password string) string {
	return ""
}

func (c *containerRuntimeCmdClient) ListAllImage() []ImageInfo {
	return nil
}

func (c *containerRuntimeCmdClient) ContainerStopAndRemove(containerID string) {

}
